#pragma once

#include <sys_def.h>

// CSR寄存器编号
typedef enum {
	CSR_MSTATUS = 0x300,
	CSR_MISA = 0x301,
	CSR_MIE = 0x304,
	CSR_MTVEC = 0x305,
	CSR_MTVT = 0x307,
	CSR_MCOUNTINHIBIT = 0x320,
	CSR_MSCRATCH = 0x340,
	CSR_MEPC = 0x341,
	CSR_MCAUSE = 0x342,
	CSR_MTVAL = 0x343,
	CSR_MIP = 0x344,
	CSR_MNXTI = 0x345,
	CSR_MINTSTATUS = 0x346,
	CSR_MSCRATCHCSW = 0x348,
	CSR_MSCRATCHCSWL = 0x349,
	CSR_MNVEC = 0x7C3,
	CSR_MSUBM = 0x7C4,
	CSR_MMISC_CTL = 0x7D0,
	CSR_MSAVESTATUS = 0x7D6,
	CSR_MSAVEEPC1 = 0x7D7,
	CSR_MSAVECAUSE1 = 0x7D8,
	CSR_MSAVEEPC2 = 0x7D9,
	CSR_MSAVECAUSE2 = 0x7DA,
	CSR_PUSHMSUBM = 0x7EB,
	CSR_MTVT2 = 0x7EC,
	CSR_JALMNXTI = 0x7ED,
	CSR_PUSHMCAUSE = 0x7EE,
	CSR_PUSHMEPC = 0x7EF,
	CSR_WFE = 0x810,
	CSR_SLEEPVALUE = 0x811,
	CSR_TXEVT = 0x812,
	CSR_MCYCLE = 0xB00,
	CSR_MINSTRET = 0xB02,
	CSR_MCYCLEH = 0xB80,
	CSR_MINSTRETH = 0xB82,
	CSR_CYCLE = 0XC00,
	CSR_TIME = 0XC01,
	CSR_INSTRET = 0XC02,
	CSR_CYCLEH = 0XC80,
	CSR_TIMEH = 0XC81,
	CSR_INSTRETH = 0XC82,
	CSR_MVENDORID = 0xF11,
	CSR_MARCHID = 0xF12,
	CSR_MIMPID = 0xF13,
	CSR_MHARTID = 0xF14,
} csr_e;

// 设置CSR寄存器的值
#define csr_wreg(csr, value) __asm__("csrw %0, %1" ::"i"(csr), "r"(value))

// 将CSR寄存器的给定位设为1
#define csr_hreg(csr, bits) __asm__("csrs %0, %1" ::"i"(csr), "r"(bits))

// 将CSR寄存器的低5位中的若干位设为1（比csr_high代价小）。
// 必须保证high_bits除低5位外全为0，否则会编译错误。
#define csr_hreg_0_4(csr, bits) __asm__("csrsi %0, %1" ::"i"(csr), "i"(bits))

// 将CSR寄存器的给定位设为0
#define csr_lreg(csr, bits) __asm__("csrc %0, %1" ::"i"(csr), "r"(bits))

// 将CSR寄存器的低5位中的若干位设为0（比csr_low代价小）。
// 必须保证low_bits除低5位外全为0，否则会编译错误。
#define csr_lreg_0_4(csr, bits) __asm__("csrci %0, %1" ::"i"(csr), "i"(bits))

// 读取CSR寄存器的值
#define csr_rreg(value, csr) __asm__("csrr %0, %1" : "=r"(value) : "i"(csr))
